﻿using Autofac;
using Autofac.Core;
using System;

namespace FF14TreasureDiggingTool.IOC;

public static class IocManager
{
    private static ILifetimeScope? _container;

    /// <summary>
    /// 初始化容器
    /// </summary>
    /// <param name="container">容器</param>
    public static void InitContainer(ILifetimeScope container)
    {
        _container = container;
    }

    /// <summary>
    /// 获取容器
    /// </summary>
    /// <exception cref="Exception">容器为空异常</exception>
    public static ILifetimeScope Container
    {
        get
        {
            if (_container == null)
            {
                throw new Exception("容器为空，请先使用InitContainer方法初始化容器，再进行使用。");
            }

            return _container;
        }
    }

    /// <summary>
    /// 获取对象
    /// </summary>
    /// <typeparam name="T">泛型T</typeparam>
    /// <returns></returns>
    /// <exception cref="Exception">容器为空异常</exception>
    public static T Resolve<T>()
        where T : notnull
    {
        if (_container == null)
        {
            throw new Exception("容器为空，请先使用SetContainer方法初始化容器，再进行使用。");
        }

        return _container.Resolve<T>();
    }

    /// <summary>
    /// 获取对象
    /// </summary>
    /// <param name="type">类型</param>
    /// <returns></returns>
    /// <exception cref="Exception">容器为空异常</exception>
    public static object Resolve(Type type)
    {
        if (_container == null)
        {
            throw new Exception("容器为空，请先使用InitContainer方法初始化容器，再进行使用。");
        }

        return _container.Resolve(type);
    }

    /// <summary>
    /// 根据Key获取对象
    /// </summary>
    /// <param name="key">键值</param>
    /// <typeparam name="T">泛型T</typeparam>
    /// <returns></returns>
    /// <exception cref="Exception">容器为空异常</exception>
    public static T ResolveByKey<T>(string key)
        where T : notnull
    {
        if (_container == null)
        {
            throw new Exception("容器为空，请先使用InitContainer方法初始化容器，再进行使用。");
        }

        return _container.ResolveKeyed<T>(key);
    }

    /// <summary>
    /// 根据键值获取对象，带参数
    /// </summary>
    /// <param name="key">键值</param>
    /// <param name="parameters">参数</param>
    /// <typeparam name="T">泛型T</typeparam>
    /// <returns></returns>
    /// <exception cref="Exception">容器为空异常</exception>
    public static T ResolveByKey<T>(string key, params Parameter[] parameters)
        where T : notnull
    {
        if (_container == null)
        {
            throw new Exception("容器为空，请先使用InitContainer方法初始化容器，再进行使用。");
        }

        return _container.ResolveKeyed<T>(key, parameters);
    }

    /// <summary>
    /// 根据名称获取对象
    /// </summary>
    /// <param name="name">名称</param>
    /// <typeparam name="T">泛型T</typeparam>
    /// <returns></returns>
    /// <exception cref="Exception">容器为空异常</exception>
    public static T ResolveByName<T>(string name)
        where T : notnull
    {
        if (_container == null)
        {
            throw new Exception("容器为空，请先使用InitContainer方法初始化容器，再进行使用。");
        }

        return _container.ResolveNamed<T>(name);
    }
}